﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UnityScriptEngine;

namespace EnrollmentSystem
{
    public partial class frmEnrollmentManager : Form
    {
        UnityProcessor proc = new UnityProcessor();
        Threader t = new Threader();
        UnityScript[] dat = new UnityScript[0];
        UnityScript[] datSched = new UnityScript[0];
        UnityElement curDatSched;

        //Operation Attributes
        bool AddNew = false;
        int curEdit = -1;
        UnityElement curData;
        string prevSrc = "";

        //Enrollment Attributes
        string EnNo = "";
        string[] studID;
        string[] studCourse;
        int[] schedID = new int[0];
        string[] scheds= new string[0];
        float[] schedPrice = new float[0];
        float[] schedUnits = new float[0];

        int schedIndex = -1;

        public frmEnrollmentManager()
        {
            InitializeComponent();
            InitializeFrameSliderForm();
        }
        private void InitializeForm()
        {
            DoEvents();

            DetailControl(true);
            grpDetails.Visible = false;
            LoadEnrollment();
        }
       
        void DoEvents()
        {
            //GUI Events
            btnAdd.Click += new EventHandler(delegate
            {
                //Proper Add New GUI
                AddNew = true;

                //DetailControl(true);
                LoadInitData();
            });
            btnCloseDetails.Click += new EventHandler(delegate
            {

                AddNew = false;
                DetailControl(false);
                foreach (Control ctl in grpDetails.Controls)
                {
                    if (ctl is TextBox) ((TextBox)ctl).Text = "";
                    if (ctl is ComboBox) ((ComboBox)ctl).SelectedIndex = -1;
                    if (ctl is DateTimePicker) ((DateTimePicker)ctl).Value = DateTime.Now;
                    if (ctl is CheckBox) ((CheckBox)ctl).Checked = false;
                    if (ctl is DataGridView) ((DataGridView)ctl).DataSource = null;
                }
                LoadEnrollment();
            });

            grdItems.DoubleClick += new EventHandler(delegate
            {
                curEdit = grdItems.SelectedRows[0].Index;
                AddNew = false;
                dat[0].Data_Get(curEdit, out curData);
                EnNo = curData.Data_GetField(0).ToString();

                LoadEnrollmentData();
            });
            txtSearch.KeyPress += new KeyPressEventHandler(delegate(object sender, KeyPressEventArgs e)
            {
                if (e.KeyChar == (char)13)
                {
                    txtPage.Value = 1m;
                    prevSrc = txtSearch.Text;
                    LoadEnrollment();
                }
            });
            txtPage.ValueChanged += new EventHandler(delegate
            {
                LoadEnrollment();
            });

            //Custom
            txtSemester.SelectedIndexChanged += new EventHandler(delegate
            {
                if (txtSemester.SelectedIndex != -1)
                {
                    LoadScheduleData();
                }
            });
            txtName.TextChanged += new EventHandler(delegate
            {
                int ind = txtName.AutoCompleteCustomSource.IndexOf(txtName.Text);
                if (ind != -1)
                {
                    txtStudID.Text = studID[ind];
                    txtCourse.Text = studCourse[ind];
                }
                else
                {
                    txtStudID.Text = "N/A";
                    txtCourse.Text = "N/A";
                }
            });
            btnSetSched.Click += new EventHandler(delegate
            {
                if (scheds.Length == 0) return;
                frmScheduleList scheddlg = new frmScheduleList();
                scheddlg.AddRange(scheds);
                DialogResult dlg = scheddlg.ShowDialog();
                if (dlg == System.Windows.Forms.DialogResult.OK)
                {
                    txtSched.Text = scheddlg.GetSchedule();
                    schedIndex = scheddlg.GetScheduleID();
                }
            });
            btnAddSched.Click += new EventHandler(delegate
            {
                if (schedIndex == -1)
                {
                    MessageBox.Show("Please select a schedule first.", "Add Schedule", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    return;
                }
                DialogResult confirmAdd = MessageBox.Show("Are you to add the subject?", "Add Subject", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (confirmAdd == System.Windows.Forms.DialogResult.No) return;
                SaveEnrollmentData();
            });
            grdScheds.Click += new EventHandler(delegate
            {
                if (grdScheds.SelectedRows.Count > 0)
                {
                    datSched[2].Data_Get(grdScheds.SelectedRows[0].Index, out curDatSched);
                }
            });
            btnDropSched.Click += new EventHandler(delegate
            {
                datSched[2].Data_Get(grdScheds.SelectedRows[0].Index, out curDatSched);
                if (curDatSched.Data_GetField(4).ToString() == "DROPPED")
                {
                    MessageBox.Show("Subject is already dropped.", "Drop Subject", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                DialogResult confirmDrop = MessageBox.Show("Are you to drop the subject?", "Drop Subject", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (confirmDrop == System.Windows.Forms.DialogResult.No) return;
                DropEnrollmentData();
            });
            //UnityScriptEngine Events
            proc.ProcessCompleted += new ProcessHandler(proc_ProcessCompleted);
            proc.ProcessError += new ProcessHandler(proc_ProcessError);
        }
        //UnityScriptEngine
        void proc_ProcessError(string id, string desc)
        {
            t.SafeCall(this, delegate
            {
                MessageBox.Show(desc);
                switch (id)
                {
                    case "LOADUSERS":
                        DetailControl(true);
                        grpDetails.Enabled = false;
                        break;
                    case "DELETEUSER":
                    case "SAVEUSER":
                        DetailControl(true);
                        break;
                }
            });
        }
        void proc_ProcessCompleted(string id, string desc)
        {
            t.SafeCall(this, delegate
            {
                switch (id)
                {
                    case "LOADENROLLMENT":
                        proc.DBPUX_Data_Fetch(out dat);
                        grdItems.DataSource = dat[0].ToDataTable();
                        if (dat[0].Data_Count == 50)
                            txtPage.Maximum = txtPage.Value + 1;
                        else
                            txtPage.Maximum = txtPage.Value;

                        AddNew = false;
                        DetailControl(false);
                        foreach (Control ctl in grpDetails.Controls)
                        {
                            if (ctl is TextBox) ((TextBox)ctl).Text = "";
                        }
                        FormatGrid();
                        break;

                    case "LOADINIT":
                        UnityScript[] usem;
                        proc.DBPUX_Data_Fetch(out usem);
                        txtSemester.Items.Clear();
                        txtSemester.Items.AddRange(usem[0].ToList(0));
                        
                        UnityElement eEno;
                        usem[1].Data_Get(0, out eEno);
                        EnNo = "EN" + int.Parse(eEno.Data_GetField(0).ToString()).ToString("000000");
                        grpDetails.Text = "Enrollment Number : " + EnNo;

                        txtName.AutoCompleteCustomSource.AddRange(usem[2].ToList<string>(1));
                        studID = usem[2].ToList<string>(0);
                        studCourse = usem[2].ToList<string>(2);

                        txtCategory.Items.Clear();
                        txtCategory.Items.AddRange(usem[3].ToList(0));

                        txtYearLevel.Items.Clear();
                        txtYearLevel.Items.AddRange(usem[4].ToList(0));

                        DetailControl(true);
                        if (AddNew)
                        {
                            txtName.Enabled = true;
                            txtSemester.Enabled = true;
                            txtCategory.Enabled = true;
                            txtYearLevel.Enabled = true;
                        }
                        break;
                    case "LOADSCHED":
                        UnityScript[] usched;
                        proc.DBPUX_Data_Fetch(out usched);
                        //txtSched.Items.Clear();
                        object[] subj = usched[0].ToList(0);
                        object[] days = usched[0].ToList(1);
                        object[] tin = usched[0].ToList(2);
                        object[] tout = usched[0].ToList(3);
                        object[] venue = usched[0].ToList(4);

                        scheds = new string[usched[0].Data_Count];
                        schedID = new int[usched[0].Data_Count];
                        schedPrice = new float[usched[0].Data_Count];
                        schedUnits = new float[usched[0].Data_Count];

                        for (int i = 0; i < usched[0].Data_Count; i++)
                        {
                            //txtSched.Items.Add(
                            UnityElement esched;
                            usched[0].Data_Get(i, out esched);
                            schedID[i] = esched.Data_ID;
                            schedPrice[i] = float.Parse(esched.Data_GetField(5).ToString());
                            schedUnits[i] = float.Parse(esched.Data_GetField(6).ToString());
                            scheds[i] = 
                                string.Format("{0}, {1}, {2}-{3}, {4}",
                                subj[i],
                                days[i],
                                tin[i],
                                tout[i],
                                venue[i]
                                );
                        }
                        break;
                    case "DROPENROLLMENTDATA":
                    case "SAVEENROLLMENTDATA":
                        LoadEnrollmentData();
                        break;
                    case "LOADENROLLMENTDATA":
                        UnityScript[] uedat;
                        proc.DBPUX_Data_Fetch(out datSched);
                        txtSemester.Items.Clear();
                        txtSemester.Items.AddRange(datSched[0].ToList(0));
                         
                        txtCategory.Items.Clear();
                        txtCategory.Items.AddRange(datSched[3].ToList(0));

                        txtYearLevel.Items.Clear();
                        txtYearLevel.Items.AddRange(datSched[4].ToList(0));

                        UnityElement eedat;
                        datSched[1].Data_Get(0, out eedat);

                        EnNo = eedat.Data_GetField(0).ToString();
                        grpDetails.Text = "Enrollment Number : " + EnNo;
                        
                        txtName.Text = eedat.Data_GetField(2).ToString();
                        txtStudID.Text = eedat.Data_GetField(1).ToString();
                        txtCourse.Text = eedat.Data_GetField(3).ToString();
                        txtSemester.Text = eedat.Data_GetField(4).ToString();
                        txtCategory.Text = eedat.Data_GetField(5).ToString();
                        txtYearLevel.Text = eedat.Data_GetField(6).ToString();
                        
                        grdScheds.DataSource = datSched[2].ToDataTable();

                        DetailControl(true);
                        txtName.Enabled = false;
                        txtSemester.Enabled = false;
                        txtCategory.Enabled = false;
                        txtYearLevel.Enabled = false;

                        FormatGrid();
                        break;
                }
            });
        }
        //Data Operations
        void LoadInitData()
        {
            UnityScript u = new UnityScript("LOADINIT", 5);
            u.Script_Add(Script.DBPUX_BEGIN);
            u.Script_Add(Script.DBPUX_QUERY, "SELECT fID, fData, fStamp FROM tbllookup WHERE fKey='SEM_SCHOOL_YEAR' ORDER BY fData DESC");
            u.Script_Add(Script.DBPUX_QUERY, "SELECT fID, fNum, fStamp FROM tblgenerator WHERE fSeries='EN'");
            u.Script_Add(Script.DBPUX_QUERY, "SELECT fID, fNumber, fName, fCourse, fStamp FROM tblstudentprofile ORDER BY fName ASC");
            u.Script_Add(Script.DBPUX_QUERY, "SELECT fID, fData, fStamp FROM tbllookup WHERE fKey='STUDENT_CATEGORY' ORDER BY fData DESC");
            u.Script_Add(Script.DBPUX_QUERY, "SELECT fID, fData, fStamp FROM tbllookup WHERE fKey='YEAR_LEVEL' ORDER BY fData DESC");
            u.Script_Add(Script.DBPUX_COMMIT);
            proc.Run(u);
        }
        void LoadScheduleData()
        {
            UnityScript u = new UnityScript("LOADSCHED", 5);
            u.Script_Add(Script.DBPUX_BEGIN);
            u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fID, fCode, fDays, TIME_FORMAT(fStartTime, '%r'), TIME_FORMAT(fEndTime, '%r'), fVenue, fPrice, fUnits, fStamp FROM tblsubjectplanner WHERE "+
                "fSchoolYear='{0}' ORDER BY fCode ASC",
                txtSemester.Text
                ));
            u.Script_Add(Script.DBPUX_COMMIT);
            proc.Run(u);
        }
        void LoadEnrollment()
        {
            UnityScript u = new UnityScript("LOADENROLLMENT", 5);
            u.Script_Add(Script.DBPUX_BEGIN);
            u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fID, fEnrollmentNumber AS 'Enrollment Number', fName AS 'Student Name', fSchoolYear AS 'SEM S.Y.', fStudentCat AS 'Category', fYearLevel as 'YearLevel',  fStamp "+
                "FROM tblenrollment T1, (SELECT fName, fNumber FROM tblstudentprofile) AS T2 WHERE (T2.fNumber = T1.fStudentNumber) AND ((fStudentNumber LIKE '%{0}%') OR (fName LIKE '%{0}%') OR "+
                "(fEnrollmentNumber LIKE '%{0}%')) ORDER BY fSchoolYear DESC, fEnrollmentNumber ASC " +
                "LIMIT {1}, 50",
                prevSrc,
                (txtPage.Value - 1m) * 50
                )
                );
            u.Script_Add(Script.DBPUX_COMMIT);
            proc.Run(u);
        }
        void LoadEnrollmentData()
        {
            DetailControl(false);
            UnityScript u = new UnityScript("LOADENROLLMENTDATA", 5);
            u.Script_Add(Script.DBPUX_BEGIN);
            u.Script_Add(Script.DBPUX_QUERY, "SELECT fID, fData, fStamp FROM tbllookup WHERE fKey='SEM_SCHOOL_YEAR' ORDER BY fData DESC");
            u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fID, fEnrollmentNumber, fStudentNumber, fName, fCourse, fSchoolYear, fStudentCat, fYearLevel, fStamp FROM tblenrollment T1, " +
                "(SELECT fNumber, fName, fCourse FROM tblstudentprofile) AS T2 WHERE " +
                "fNumber=fStudentNumber AND fEnrollmentNumber='{0}'", 
                EnNo
                )
                );
            u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fID, fSubjectCode AS 'Code', fCode AS 'Subject Name', fUnits AS 'Units', fPrice AS 'Price', fRemarks AS 'Remarks', fStamp FROM tblenrollmentdetail T1, " +
                "(SELECT fID AS ffID, fCode, fUnits, fPrice FROM tblsubjectplanner T22) AS T2 WHERE " +
                "(ffID = fSubjectCode) AND (fEnrollmentNumber='{0}')",
                EnNo
                )
                );
            u.Script_Add(Script.DBPUX_QUERY, "SELECT fID, fData, fStamp FROM tbllookup WHERE fKey='STUDENT_CATEGORY' ORDER BY fData DESC");
            u.Script_Add(Script.DBPUX_QUERY, "SELECT fID, fData, fStamp FROM tbllookup WHERE fKey='YEAR_LEVEL' ORDER BY fData DESC");
            u.Script_Add(Script.DBPUX_COMMIT);
            proc.Run(u);
        }
        void SaveEnrollmentData()
        {
            grpDetails.Enabled = false;
            UnityScript u = new UnityScript("SAVEENROLLMENTDATA", 5);
            u.Script_Add(Script.DBPUX_BEGIN);
            if (AddNew)
            {
                AddNew = false;
                u.Script_Add(Script.DBPUX_INSERT, "tblenrollment(fEnrollmentNumber, fStudentNumber, fStudentCat, fYearLevel, fSchoolYear)",
                    new string[]{
                      EnNo,
                      txtStudID.Text,
                      txtCategory.Text,
                      txtYearLevel.Text,
                      txtSemester.Text
                    });
                u.Script_Add(Script.DBPUX_INSERT, "tblenrollmentdetail(fEnrollmentNumber, fSubjectCode, fRemarks)",
                    new string[]{
                      EnNo,
                      schedID[schedIndex].ToString(),
                      "CURRENT"
                    });
                u.Script_Add(Script.DBPUX_INSERT, "tblgrades(fEnrollmentNum, fSubjectCode, fGrade, fUnits, fRemarks)",
                    new string[]{
                        EnNo,
                        schedID[schedIndex].ToString(),
                        "0.0",
                        schedUnits[schedIndex].ToString(),
                        "CURRENT"
                    });
                u.Script_Add(Script.DBPUX_INSERT, "tblsalesdetail(fEnrollmentNum, fItem, fQty, fPrice)",
                    new string[]{
                        EnNo,
                        "TUITION",
                        "1",
                        schedPrice[schedIndex].ToString()
                    });
                u.Script_Add(Script.DBPUX_UPDATE, "tblgenerator SET fNum=fNum+1", "(fSeries='EN')");
            }
            else
            {
                u.Script_Add(Script.DBPUX_INSERT, "tblenrollmentdetail(fEnrollmentNumber, fSubjectCode, fRemarks)",
                    new string[]{
                      EnNo,
                      schedID[schedIndex].ToString(),
                      "CURRENT"
                    });
                u.Script_Add(Script.DBPUX_INSERT, "tblgrades(fEnrollmentNum, fSubjectCode, fGrade, fUnits, fRemarks)",
                    new string[]{
                        EnNo,
                        schedID[schedIndex].ToString(),
                        "0.0",
                        schedUnits[schedIndex].ToString(),
                        "CURRENT"
                    });
                u.Script_Add(Script.DBPUX_UPDATE, string.Format("tblsalesdetail SET fPrice=fPrice+{0}",
                        schedPrice[schedIndex].ToString()
                    ),
                    string.Format("(fEnrollmentNum='{0}')",EnNo)
                    );
            }

            u.Script_Add(Script.DBPUX_COMMIT);
            proc.Run(u);
        }
        void DropEnrollmentData()
        {
            grpDetails.Enabled = false;
            UnityScript u = new UnityScript("DROPENROLLMENTDATA", 5);
            u.Script_Add(Script.DBPUX_BEGIN);
            u.Script_Add(Script.DBPUX_UPDATE, "tblenrollmentdetail SET fRemarks='DROPPED'",
                string.Format("(fID='{0}')AND(fStamp='{1}')",
                curDatSched.Data_ID.ToString(),
                curDatSched.Data_Stamp.ToString()
                )
                );
            u.Script_Add(Script.DBPUX_UPDATE, "tblgrades SET fRemarks='DROPPED'",
                string.Format("(fEnrollmentNum='{0}') AND (fSubjectCode='{1}')",
                EnNo,
                curDatSched.Data_GetField(0)
                )
                );
            u.Script_Add(Script.DBPUX_UPDATE, string.Format("tblsalesdetail SET fPrice=fPrice-{0}",
                        curDatSched.Data_GetField(3)
                    ),
                    string.Format("(fEnrollmentNum='{0}')", EnNo)
                    );
            u.Script_Add(Script.DBPUX_COMMIT);
            proc.Run(u);
        }

        //GUI Operations
        void DetailControl(bool s)
        {
            grdItems.Enabled = !s;
            grpDetails.Visible = s;
            grpDetails.Enabled = s;
            btnAdd.Enabled = !s;
            txtSearch.Enabled = !s;
            txtPage.Enabled = !s;
        }
        void AddSchedControl(bool s)
        {
            grdScheds.Enabled = s;
            btnSetSched.Enabled = s;
            btnDropSched.Enabled = s;
            btnAddSched.Enabled = s;
        }
        void FormatGrid()
        {
            foreach (DataGridViewColumn col in grdItems.Columns)
            {
                col.Width = (grdItems.Width / grdItems.Columns.Count) - 10;
                col.SortMode = DataGridViewColumnSortMode.NotSortable;
            }
            foreach (DataGridViewColumn col in grdScheds.Columns)
            {
                col.Width = (grdScheds.Width / grdScheds.Columns.Count) - 10;
                col.SortMode = DataGridViewColumnSortMode.NotSortable;
            }
        }
        
    }
}
